package service

import (
	"context"
	"encoding/json"
	"fx_swift_ifcgate_agent/api"
	"fx_swift_ifcgate_agent/internal/model"
	"fx_swift_ifcgate_agent/pkg/code"
	"fx_swift_ifcgate_agent/pkg/global"
	"fx_swift_ifcgate_agent/pkg/internalerrors"
	"fx_swift_ifcgate_agent/pkg/logger"
	"fx_swift_ifcgate_agent/pkg/page"
	"github.com/spf13/cast"
)

type ITransferSrv interface {
	// 收款记录
	TradeReceiptList(ctx context.Context, req *api.TradeReceiptListReq) (*page.Collection[*api.TradeReceiptInfoRes], error)

	//收款关联还原材料
	TradeReceiptOrderDetail(ctx context.Context, flowNo string) (*api.TradeReceiptOrderDetailRes, error)

	// 国际汇款记录
	InternationTransferList(ctx context.Context, req *api.ITListReq) (*page.Collection[*api.ITListRes], error)

	// 国内汇款记录
	DomesticTransferList(ctx context.Context, req *api.DTListReq) (*page.Collection[*api.DTListRes], error)

	// 国内汇款记录详情
	DomesticTransferDetail(ctx context.Context, merOrderNo string) (*api.DomesticTransferDetailReq, error)
}

type transferSrv struct {
}

func NewTransferSrv() ITransferSrv {
	return &transferSrv{}
}

// 收款记录
func (t *transferSrv) TradeReceiptList(ctx context.Context, req *api.TradeReceiptListReq) (*page.Collection[*api.TradeReceiptInfoRes], error) {
	var (
		err        error
		total      int
		account    string
		resultList []*api.TradeReceiptInfoRes
	)

	collectionDto := &page.Collection[*api.TradeReceiptInfoRes]{}
	collectionDto.Page = uint64(req.PageNo)
	collectionDto.PageSize = uint64(req.PageSize)

	account = ctx.Value("Account").(string)

	mod := global.GFDB.Ctx(ctx).Schema("fx").Model("fx.ifcgate_trade_receipt itr").
		LeftJoin("fx.ifcgate_vainfo_call_back ivcb", "itr.va_account=ivcb.account_no").
		LeftJoin("fx.ifcgate_merchant_va_info imvi", "imvi.merchant_no=itr.merchant_no").
		Fields("itr.flow_no,itr.receive_amount,itr.actual_receive_amount,itr.receive_currency,itr.sender_name,itr.sender_account," +
			"itr.created_at,itr.fee_amount,itr.fee_currency,itr.trade_status,itr.trade_message,ivcb.account_name,ivcb.account_no,imvi.mer_name_en,imvi.mer_name_cn")
	if len(req.FlowNo) > 0 {
		mod.Where("itr.flow_no like ?", "%"+req.FlowNo+"%")
	}
	if len(req.ReceiveCurrency) > 0 {
		mod.Where("itr.receive_currency=?", req.ReceiveCurrency)
	}
	if len(req.CompanyName) > 0 {
		mod.Where("imvi.mer_name_en like ? or imvi.mer_name_cn like ?", "%"+req.CompanyName+"%", "%"+req.CompanyName+"%")
	}
	if len(req.StartTime) > 0 && len(req.EndTime) > 0 {
		mod.Where("itr.created_at >=? and itr.created_at < ?", req.StartTime+" 00:00:00", req.EndTime+" 23:59:59")
	}
	mod.Where("itr.account=?", account)
	mod.Order("itr.created_at desc")
	mod.Limit(int(page.PageToOffset(uint64(req.PageNo), uint64(req.PageSize))), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(uint64(req.PageNo), uint64(req.PageSize), cast.ToInt64(total))
	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList
	return collectionDto, err
}

// 收款关联还原材料
func (t *transferSrv) TradeReceiptOrderDetail(ctx context.Context, flowNo string) (*api.TradeReceiptOrderDetailRes, error) {
	var (
		tradeOrderCallBackObj *model.IfcgateTradeOrderCallBack
		tradeReceiptOrder     *model.IfcgateTradeReceiptOrder
		result                *api.TradeReceiptOrderDetailRes
		err                   error
	)
	if err = global.GFDB.Ctx(ctx).Model("ifcgate_trade_order_call_back").
		Where("flow_no=?", flowNo).Scan(&tradeOrderCallBackObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, err.Error())
	}
	if tradeOrderCallBackObj != nil {
		if err = global.GFDB.Ctx(ctx).Model("ifcgate_trade_receipt_order").
			Where("mer_order_no=?", tradeOrderCallBackObj.MerOrderNo).Scan(&tradeReceiptOrder); err != nil {
			logger.SugarLogger.Error(err)
			return nil, internalerrors.New(code.ErrUnknown, err.Error())
		}
		json.Unmarshal([]byte(tradeReceiptOrder.JsonStr), &result)
	}
	return result, err
}

// 国际汇款记录
func (t *transferSrv) InternationTransferList(ctx context.Context, req *api.ITListReq) (*page.Collection[*api.ITListRes], error) {
	var (
		err        error
		total      int
		account    string
		resultList []*api.ITListRes
	)
	account = ctx.Value("Account").(string)
	collectionDto := &page.Collection[*api.ITListRes]{}
	collectionDto.Page = uint64(req.PageNo)
	collectionDto.PageSize = uint64(req.PageSize)

	mod := global.GFDB.Ctx(ctx).Schema("fx").Model("fx.ifcgate_internation_transfer_record itr")
	mod.LeftJoin("fx.ifcgate_internation_payee iip", "itr.payee_id=iip.id")
	mod.LeftJoin("fx.ifcgate_merchant_va_info imvi", "imvi.merchant_no=itr.merchant_no")
	mod.LeftJoin("fx.ifcgate_purpose_base ipb", "ipb.code=itr.purpose")
	mod.Fields("iip.payee_first_name,iip.payee_last_name,iip.payee_bank_account_no," +
		"itr.biz_flow,itr.arrive_amount,itr.debit_amount,itr.debit_currency,itr.arrive_currency,itr.rate," +
		"itr.fee_amt,itr.status,itr.message as resp_desc,itr.fee_currency,itr.purpose,iip.payee_bank_name,iip.payee_company_name," +
		"itr.created_at,itr.updated_at,imvi.mer_name_en,imvi.mer_name_cn,itr.trade_comments,itr.purpose_remark,itr.pay_type,ipb.desc_zh purpose_desc")
	if len(req.BizFlow) > 0 {
		mod.WhereLike("itr.biz_flow", "%"+req.BizFlow+"%")
	}
	if len(req.Status) > 0 {
		mod.Where("itr.status=?", req.Status)
	}

	if len(req.StartTime) > 0 && len(req.EndTime) > 0 {
		mod.Where("itr.created_at >=? and itr.created_at < ?", req.StartTime+" 00:00:00", req.EndTime+" 23:59:59")
	}
	mod.Where("itr.account=?", account)
	mod.Order("itr.created_at desc")
	mod.Limit(int(page.PageToOffset(uint64(req.PageNo), uint64(req.PageSize))), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(uint64(req.PageNo), uint64(req.PageSize), cast.ToInt64(total))
	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList
	return collectionDto, err
}

// 国内汇款记录
func (t *transferSrv) DomesticTransferList(ctx context.Context, req *api.DTListReq) (*page.Collection[*api.DTListRes], error) {
	var (
		err        error
		total      int
		account    string
		resultList []*api.DTListRes
	)

	NewVAInfoSrv().GetTradeCodeType(ctx)

	account = ctx.Value("Account").(string)
	collectionDto := &page.Collection[*api.DTListRes]{}
	collectionDto.Page = uint64(req.PageNo)
	collectionDto.PageSize = uint64(req.PageSize)

	mod := global.GFDB.Ctx(ctx).Schema("fx").Model("fx.ifcgate_domestic_transfer_record idr")
	mod.LeftJoin("fx.ifcgate_domestic_payee idp", "idr.payee_id=idp.id")
	mod.LeftJoin("fx.ifcgate_merchant_va_info imvi", "imvi.merchant_no=idr.merchant_no")
	mod.Fields("idp.payee_name,idp.bank_acct_no,idr.resp_desc," +
		"idr.biz_flow_no,idr.amount,idr.debit_amount,idr.debit_currency,idr.status,idr.rate,idr.fee_amount,idr.status," +
		"idr.fee_currency,idr.fee_amount feeAmt,idr.created_at,idr.updated_at,idr.settlement_type," +
		"imvi.mer_name_en,imvi.mer_name_cn,idp.branch_name,idr.mer_order_no,idp.branch_name,idr.trade_code_type")
	if len(req.BizFlowNo) > 0 {
		mod.WhereLike("idr.biz_flow_no", "%"+req.BizFlowNo+"%")
	}
	if len(req.Status) > 0 {
		mod.Where("idr.status=?", req.Status)
	}
	if len(req.StartTime) > 0 && len(req.EndTime) > 0 {
		mod.Where("idr.created_at >=? and idr.created_at <= ?", req.StartTime+" 00:00:00", req.EndTime+" 23:59:59")
	}
	mod.Where("idr.account=?", account)
	mod.Order("idr.created_at desc")
	mod.Limit(int(page.PageToOffset(uint64(req.PageNo), uint64(req.PageSize))), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(uint64(req.PageNo), uint64(req.PageSize), cast.ToInt64(total))
	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	for _, value := range resultList {
		if _, ok := global.TradeCodeMap[value.TradeCodeType]; ok {
			value.TradeCodeType = global.TradeCodeMap[value.TradeCodeType]
		}
	}
	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList
	return collectionDto, err
}

// 国内汇款记录详情
func (t *transferSrv) DomesticTransferDetail(ctx context.Context, merOrderNo string) (*api.DomesticTransferDetailReq, error) {
	var (
		err               error
		transferRecordObj *model.IfcgateDomesticTransferRecord
		transferOrderList []*model.IfcgateDomesticTransferOrder
		result            = &api.DomesticTransferDetailReq{}
		list              = make([]api.TradeOrderInfo, 0)
	)
	if err = global.GFDB.Ctx(ctx).Model("ifcgate_domestic_transfer_record").
		Where("mer_order_no=?", merOrderNo).Scan(&transferRecordObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, err.Error())
	}
	if len(transferRecordObj.FileUrlPath) > 0 {
		result.FileUrlPath = transferRecordObj.FileUrlPath
		return result, err
	}
	if err = global.GFDB.Ctx(ctx).Model("ifcgate_domestic_transfer_order").
		Where("mer_order_no=?", merOrderNo).Scan(&transferOrderList); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, err.Error())
	}
	if len(transferOrderList) > 0 {
		for _, value := range transferOrderList {
			list = append(list, api.TradeOrderInfo{
				GoodNumber:    value.GoodNumber,
				GoodsName:     value.GoodsName,
				OrderAmount:   value.OrderAmount,
				OrderCurrency: value.OrderCurrency,
				OrderNo:       value.OrderNo,
				OrderDate:     value.OrderDate,
				PlatformName:  value.PlatformName,
				Purpose:       value.Purpose,
				StoreLink:     value.StoreLink,
				WlName:        value.WlName,
				WlSeqno:       value.WlSeqno,
				PayeeAcctNo:   value.PayeeAcctNo,
			})
		}
		result.TradeOrderInfo = list
	}
	return result, err
}
